package com.wss.lsl.test.driven.concurrent;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Exchanger;
import java.util.concurrent.TimeUnit;

public class ExchangerDemo {
	
	
	public static void main(String[] args) throws InterruptedException {
		Exchanger<Map<String, String>> exchanger = new Exchanger<Map<String, String>>();

		new Thread(new ReadRunnable(exchanger)).start();
		new Thread(new WriteRunnable(exchanger)).start();
		
		TimeUnit.SECONDS.sleep(5);
	}

}

class ReadRunnable implements Runnable {

	private Exchanger<Map<String, String>> exchanger;
	private Map<String, String> bufferList = new HashMap<String, String>();

	public ReadRunnable(Exchanger<Map<String, String>> exchanger) {
		super();
		this.exchanger = exchanger;
	}
	
	@Override
	public void run() {
		System.out.println("read thread start!");
		try {
			while(!Thread.interrupted()){
				for (int i = 0; i < 10; i++) {
					bufferList.put("A" + i, "A" + i);
				}
				System.out.println("read before exchange bufferList:" + bufferList);
				bufferList = exchanger.exchange(bufferList);
				System.out.println("read after exchange bufferList:" + bufferList);
			}
		} catch (InterruptedException e) {
			// ignore
		}
	}

}

class WriteRunnable implements Runnable {

	private Exchanger<Map<String, String>> exchanger;
	private Map<String, String> bufferList;

	public WriteRunnable(Exchanger<Map<String, String>> exchanger) {
		super();
		this.exchanger = exchanger;
	}

	@Override
	public void run() {
		System.out.println("write thread start!");
		try {
			while(!Thread.interrupted()) {
				System.out.println("write before exchange bufferList:" + bufferList);
				bufferList = exchanger.exchange(bufferList);
				System.out.println("write after exchange bufferList:" + bufferList);
				for (Map.Entry<String, String> entry : bufferList.entrySet()) {
					System.out.println("B " + entry.getValue());
				}
			}
		} catch (InterruptedException e) {
			// ignore
		}
	}

}
